/***************************************************************************
 * File name: q4.c
 * Author:  Tomer Filiba
 *          037013075
 *          sebulba@t2
 *
 * Exercise #: 3
 * Question #: 4
 * Submission Date: 01/7/07
 **************************************************************************/

/*-------------------------------------------------------------------------
  Include files:
--------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>

/*=========================================================================
  Constants and definitions:
==========================================================================*/
#define GREAT_SUCCESS		(0)
#define BIG_BAGA_BOOM		(1)
#define HISTOGRAM_MIN_VALUE	(1)
#define HISTOGRAM_MAX_VALUE	(9)
#define HISTOGRAM_SIZE		(HISTOGRAM_MAX_VALUE - HISTOGRAM_MIN_VALUE + 1)


/* enum of reader states */
enum reader_states
{
	RS_CHAR_ONLY,
	RS_NUMBER_ONLY,
	RS_NUMBER_OR_CHAR,
};


/*-------------------------------------------------------------------------
  Reads an RLE string from the user and decodes it. Also prints histogram.
 -------------------------------------------------------------------------*/
int main(int argc, const char ** argv) 
{
	char curr_char = '\0';
	int i;
	int ch = EOF, count = 0, total = 0;
	int histogram[HISTOGRAM_SIZE] = {0};
	int unspecific = 0;
	enum reader_states state = RS_CHAR_ONLY;
	
	/* read chars from stdin, check validity, expand RLEs and update statistics */
	printf("Enter RLE string: ");
	while (0 == 0)
	{
		ch = getchar();
		if (ch == EOF || ch == '\n' || ch == '\0') {
			printf("\nError! Input must end with an exclamation point\n");
			return BIG_BAGA_BOOM;
		}
		else if (ch == '!') {
			if (state == RS_NUMBER_ONLY) {
				printf("\nError! Expeceted digit, found '!'\n");
				return BIG_BAGA_BOOM;
			}
			/* valid end of string */
			break;
		}
		else if (ch >= '0' && ch <= '9') {
			if (state == RS_CHAR_ONLY) {
				printf("\nError! Expeceted char, found digit '%c'\n", ch);
				return BIG_BAGA_BOOM;
			}
			count = count * 10 + ch - '0';
			state = RS_NUMBER_OR_CHAR;
		}
		else if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
			if (state == RS_NUMBER_ONLY) {
				printf("\nError! Expeceted digit, found char '%c'\n", ch);
				return BIG_BAGA_BOOM;
			}
			/* print RLE element, update statistics */
			for (i = 0; i < count; i++)
				putchar(curr_char);
			total += count;
			if (count >= HISTOGRAM_MIN_VALUE && count <= HISTOGRAM_MAX_VALUE)
				histogram[count - HISTOGRAM_MIN_VALUE] += count;
			else
				unspecific += count;
			count = 0;
			curr_char = ch;
			state = RS_NUMBER_ONLY;
		}
		else {
			printf("\nInvalid character '%c'\n", ch);
			return BIG_BAGA_BOOM;
		}
	}
	
	/* don't forget the last RLE element */
	for (i = 0; i < count; i++)
		putchar(curr_char);
	total += count;
	if (count >= HISTOGRAM_MIN_VALUE && count <= HISTOGRAM_MAX_VALUE)
		histogram[count - HISTOGRAM_MIN_VALUE] += count;
	else
		unspecific += count;
	putchar('\n');
	
	/* print histogram, only if the string was not empty */
	if (total > 0) {
		printf("\n-------------------------------\n");
		for (i = HISTOGRAM_MIN_VALUE; i <= HISTOGRAM_MAX_VALUE; i++) {
			printf("%d: %0.2lf\n", i, 
				histogram[i - HISTOGRAM_MIN_VALUE] / (double)total);
		}
		printf("All other instances: %0.2lf\n", unspecific / (double)total);
	}
	
	return GREAT_SUCCESS;
}


/**************************************************************************
                               End of file
***************************************************************************/